package cc.magicjson.example.demo.event;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static cc.magicjson.example.demo.event.EventSource.fireEventAndNotifyAsync;

// 自定义事件类型
class CustomEvent {
    private String message;

    public CustomEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

// 事件监听器接口
interface EventListener {
    void onEvent(CustomEvent event);
}

// 事件源类
class EventSource {
    private final List<EventListener> listeners = new CopyOnWriteArrayList<>();

    // 注册监听器
    public void register(EventListener listener) {
        listeners.add(listener);
    }

    // 移除监听器
    public void unregister(EventListener listener) {
        listeners.remove(listener);
    }

    // 触发事件并通知所有监听器
    public void fireEvent(CustomEvent event) {
        listeners.forEach(listener -> listener.onEvent(event));
    }

    public static void fireEventAndNotifyAsync(EventSource source, ExecutorService executor, CustomEvent event) {
        executor.execute(() -> source.fireEvent(event));
    }
}

// 主函数，模拟事件通知过程
public class Main {
    public static void main(String[] args) {
        // 创建事件源
        EventSource eventSource = new EventSource();

        // 创建两个监听器
        EventListener listener1 = event -> System.out.println("Listener 1 received: " + event.getMessage());
        EventListener listener2 = event -> System.out.println("Listener 2 received: " + event.getMessage());

        // 注册监听器
        eventSource.register(listener1);
        eventSource.register(listener2);

        // 创建一个事件并触发
        CustomEvent customEvent = new CustomEvent("Hello, World!");
        eventSource.fireEvent(customEvent);

        // 如果需要异步通知，可以使用ExecutorService
        ExecutorService executor = Executors.newSingleThreadExecutor();
        fireEventAndNotifyAsync(eventSource, executor, customEvent);

        // 不要忘记在程序结束前关闭executor
        executor.shutdown();
    }

    // 异步通知的辅助方法（模拟）

}